package com.zhuoyue.web.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhuoyue.biz.core.api.dao.LocalSceneGatewayRelationMapper;
import com.zhuoyue.biz.core.api.dao.LocalSceneInfraredDeviceRelationMapper;
import com.zhuoyue.biz.core.api.dao.LocalSceneZigbeeDeviceRelationMapper;
import com.zhuoyue.biz.core.api.domain.*;
import com.zhuoyue.biz.core.api.dto.rep.GatewayTimeTaskRepDTO;
import com.zhuoyue.biz.core.api.dto.req.GatewayTimeTaskReqPutDTO;
import com.zhuoyue.biz.core.api.service.GatewayService;
import com.zhuoyue.biz.core.api.service.impl.GatewayTimingSceneService;
import com.zhuoyue.biz.core.api.dto.req.GatewayTimeTaskReqDTO;
import com.zhuoyue.biz.core.api.service.impl.LocalSceneService;
import com.zhuoyue.common.aop.auth.CheckLogin;
import com.zhuoyue.common.dto.ControllerResult;
import com.zhuoyue.common.exception.ErrorType;
import com.zhuoyue.common.exception.ZyServerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wjming
 */
@RestController
@Scope("prototype")
@RequestMapping("/api/gateway/timed")
@Validated
@Slf4j(topic = "GatewayController")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AppGatewayTimeTaskController {

    private final LocalSceneGatewayRelationMapper gatewayRelation;
    private final LocalSceneZigbeeDeviceRelationMapper zigbeeDeviceRelationMapper;
    private final LocalSceneInfraredDeviceRelationMapper infraredDeviceRelationMapper;
    private final GatewayTimingSceneService gatewayTimingSceneService;
    private final GatewayService gatewayService;
    private final LocalSceneService localSceneService;

    /**
     * 获取网关定时配置
     *
     * @param gatewayId
     * @return
     */
    @GetMapping
    @CheckLogin
    public ControllerResult gatewayTimeSet(@NotBlank(message = "网关ID不能为空") String gatewayId) {
        List<GatewayTimeTaskRepDTO> gatewayTimeTaskRepDTO = gatewayTimingSceneService.getByGatewayId(gatewayId);
        return ControllerResult.toReturnDataSuccess("获取成功", gatewayTimeTaskRepDTO);
    }

    @PostMapping
    @CheckLogin
    public ControllerResult addGatewayTimeSet(@RequestBody GatewayTimeTaskReqDTO gatewayTimeTaskReqDTO) {
        GatewayDO gateway = gatewayService.getById(gatewayTimeTaskReqDTO.getGatewayId());
        if (gateway == null) {
            throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "网关不存在");
        }
        LocalSceneDO localSceneDO = localSceneService.getById(gatewayTimeTaskReqDTO.getDealId());
        if (localSceneDO == null) {
            throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "场景不存在或场景中的控制设备不能为空");
        }
        //查询编号是否可用
        List<GatewayTimingScene> gatewayTimingScenes = gatewayTimingSceneService.list(Wrappers.<GatewayTimingScene>lambdaQuery()
                .eq(GatewayTimingScene::getGatewayId, gateway.getId()));
        List<Integer> taskIndex = gatewayTimingScenes.stream().map(gatewayTimingScene -> gatewayTimingScene.getTaskIndex()).collect(Collectors.toList());
        int allSize = 8;
        if (CollectionUtils.isNotEmpty(gatewayTimingScenes) && gatewayTimingScenes.size() >= allSize) {
            throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "定时任务已满");
        }
        int code = 1;
        if (gatewayTimingScenes.size() < 1) {
        } else {
            Map<Integer, Integer> map = new HashMap<>(5);
            for (Integer c : taskIndex) {
                if (null != c) {
                    map.put(c, c);
                }
            }
            for (int i = 1; i < allSize + 1; i++) {
                if (null == map.get(i)) {
                    code = i;
                    break;
                }
            }
        }
        gatewayTimeTaskReqDTO.setTaskIndex(code);
        gatewayTimingSceneService.setTimeTask(localSceneDO, gatewayTimeTaskReqDTO, gateway);
        return ControllerResult.toReturnMessageSuccess("配置命令已发送");
    }

    @PutMapping
    @CheckLogin
    public ControllerResult putGatewayTimeSet(@RequestBody GatewayTimeTaskReqPutDTO gatewayTimeTaskReqPutDTO) {
        GatewayTimingScene gatewayTimingScene = gatewayTimingSceneService.getById(gatewayTimeTaskReqPutDTO.getId());
        if (gatewayTimingScene == null) {
            return ControllerResult.toFail("修改信息不存在");
        }
        gatewayTimeTaskReqPutDTO.setTaskIndex(gatewayTimingScene.getTaskIndex());
        gatewayTimeTaskReqPutDTO.setGatewayId(gatewayTimingScene.getGatewayId());
        if (StringUtils.isEmpty(gatewayTimeTaskReqPutDTO.getDealId())) {
            gatewayTimingSceneService.putTimeTask(gatewayTimeTaskReqPutDTO);
        } else {
            LocalSceneDO localSceneDO = localSceneService.getById(gatewayTimeTaskReqPutDTO.getDealId());
            if (localSceneDO == null) {
                throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "场景不存在或场景中的控制设备不能为空");
            }
            gatewayTimingSceneService.putTimeTask(localSceneDO, gatewayTimeTaskReqPutDTO);
        }
        return ControllerResult.toReturnMessageSuccess("配置命令已发送");
    }

    @DeleteMapping
    @CheckLogin
    public ControllerResult deleteGatewayTimeSet(@NotBlank(message = "定时任务ID不能为空") String id) {
        gatewayTimingSceneService.removeById(id);
        return ControllerResult.toReturnMessageSuccess("配置命令已发送");
    }

    @DeleteMapping("/clear")
    @CheckLogin
    public ControllerResult clearGatewayTimeSet(@NotBlank(message = "网关ID不能为空") String gatewayId) {
        gatewayTimingSceneService.clearTimed(gatewayId);
        return ControllerResult.toReturnMessageSuccess("清空成功");
    }


    /**
     * 场景是否为空
     *
     * @param sceneId
     * @return
     */
    private Boolean sceneRelationIsNull(String sceneId) {
        Integer integer = gatewayRelation.selectCount(Wrappers.<LocalSceneGatewayRelation>lambdaQuery()
                .eq(LocalSceneGatewayRelation::getSceneId, sceneId));
        Integer integer1 = zigbeeDeviceRelationMapper.selectCount(Wrappers.<LocalSceneZigbeeDeviceRelation>lambdaQuery()
                .eq(LocalSceneZigbeeDeviceRelation::getSceneId, sceneId));
        Integer integer2 = infraredDeviceRelationMapper.selectCount(Wrappers.<LocalSceneInfraredDeviceRelation>lambdaQuery()
                .eq(LocalSceneInfraredDeviceRelation::getSceneId, sceneId));
        return (integer + integer1 + integer2) >= 1;
    }
}
